﻿using ShenGu.Script;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ScriptTest
{
    public partial class ScriptBuildForm : Form
    {
        public ScriptBuildForm(string script)
        {
            InitializeComponent();
            if (!string.IsNullOrEmpty(script)) txtContent.Text = script;
        }

        private DataTable CreateUserTable()
        {
            DataTable table = new DataTable("Users");
            table.Columns.Add("UserId", typeof(string));
            table.Columns.Add("UserName", typeof(string));
            table.Columns.Add("Age", typeof(int));
            table.Rows.Add("Admin", "管理员", 25);
            table.Rows.Add("Tester", "测试人员", 24);
            return table;
        }

        private void btnBuild_Click(object sender, EventArgs e)
        {
            try
            {
                string text = txtContent.Text;

                //将包含<@XXX></@XXX>的标签，转成可以执行的javascript语法
                TemplateParser reader = new TemplateParser();
                string script = reader.Parse(text, true);

                //解析javascript语法
                ScriptParser parser = ScriptParser.Parse(script);

                //创建脚本上下文
                ScriptContext context = new ScriptContext();
                context.AddValue("users", CreateUserTable());
                context.AddValue("status", 3);

                //执行javascript脚本
                TestScriptExecutor executor = new TestScriptExecutor(text);
                reader.Execute(parser, context, executor);

                //读取结果
                string content = executor.ToString();

                using (ScriptBuildResultForm form = new ScriptBuildResultForm(script, content))
                    form.ShowDialog();
            }
            catch(Exception ex)
            {
                MessageBox.Show("出现异常：" + ex.Message);
            }
        }
    }

    class TestScriptExecutor : StringTemplateExecutor
    {
        private Dictionary<string, TemplateImportSource> dicImport = new Dictionary<string, TemplateImportSource>(StringComparer.OrdinalIgnoreCase);

        public TestScriptExecutor(string source) : base(source) { }

        protected override TemplateImportSource OnGetImportSource(ScriptContext context, string path)
        {
            TemplateImportSource source;
            if (!dicImport.TryGetValue(path, out source))
            {
                string content = Utils.GetBuildContent(path);
                TemplateParser reader = new TemplateParser();
                string script = reader.Parse(content, true);
                ScriptParser parser = ScriptParser.Parse(script);

                dicImport[path] = source = TemplateImportSource.CreateByTemplate(path, parser, content);
            }
            return source;
        }
    }
}
